package logger

import (
	"context"
	"fmt"
	"io"
	"log/slog"
	"os"
	"path/filepath"
	"sync"

	"github.com/toolkits/file"
)

var (
	once   sync.Once
	logger *slog.Logger
)

const (
	DebugLevel = "debug"
	InfoLevel  = "info"
	WarnLevel  = "warn"
	ErrorLevel = "error"
	FatalLevel = "fatal"
)

func NewLogger(name string) error {

	logFileName := filepath.Join(file.SelfDir(), "logs", fmt.Sprintf("%s.log", name))
	once.Do(func() {
		// log home
		logHome := filepath.Join(file.SelfDir(), "logs")
		if !file.IsExist(logHome) {
			if err := os.MkdirAll(logHome, 0755); err != nil {
				panic(fmt.Sprintf("create log home failed: %v", err))
			}
		}

		// new file handler
		logFile, err := os.OpenFile(logFileName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
		if err != nil {
			panic(fmt.Sprintf("open log file failed: %v", err))
		}
		defer logFile.Close()
		handlers := slog.NewTextHandler(io.MultiWriter(os.Stdout, logFile), nil)
		logger = slog.New(handlers)

	})
	return nil
}

func Debug(msg string) {
	logger.DebugContext(context.Background(), msg)
}

func Debugf(format string, args ...any) {
	logger.DebugContext(context.Background(), fmt.Sprintf(format, args...))
}

func Info(msg string) {
	logger.InfoContext(context.Background(), msg)
}

func Infof(format string, args ...any) {
	logger.InfoContext(context.Background(), fmt.Sprintf(format, args...))
}

func Warn(msg string) {
	logger.WarnContext(context.Background(), msg)
}

func Warnf(format string, args ...any) {
	logger.WarnContext(context.Background(), fmt.Sprintf(format, args...))
}

func Error(msg string) {
	logger.ErrorContext(context.Background(), msg)
}

func Errorf(format string, args ...any) {
	logger.ErrorContext(context.Background(), fmt.Sprintf(format, args...))
}

func Fatal(msg string) {
	logger.ErrorContext(context.Background(), msg)
	os.Exit(1)
}

func Fatalf(format string, args ...any) {
	logger.ErrorContext(context.Background(), fmt.Sprintf(format, args...))
	os.Exit(1)
}
